package com.littcore.saap.assistant.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Resource;

import org.mvel2.templates.TemplateRuntime;
import org.springframework.web.context.request.WebRequest;

import com.littcore.common.BeanManager;
import com.littcore.common.Utility;
import com.littcore.dao.BaseJdbcDao;
import com.littcore.dao.IResultsetTransformer;
import com.littcore.dao.page.IPageList;
import com.littcore.dao.ql.PageParam;
import com.littcore.saap.assistant.dao.QuickviewDao;
import com.littcore.saap.assistant.dao.QuickviewFilterDao;
import com.littcore.saap.assistant.po.Quickview;
import com.littcore.saap.assistant.po.QuickviewFilter;
import com.littcore.saap.assistant.service.IQuickviewService;
import com.littcore.saap.assistant.vo.QuickviewVo;
import com.littcore.saap.assistant.webservice.IQuickviewWebService;
import com.littcore.saap.common.vo.LoginUserVo;
import com.littcore.saap.common.vo.TenantUserVo;
import com.littcore.saap.core.module.dynamicform.model.Field;
import com.littcore.saap.core.module.dynamicform.model.FieldItem;
import com.littcore.saap.core.module.dynamicform.model.FieldItems;
import com.littcore.saap.core.module.quickview.QuickviewManager;
import com.littcore.saap.core.module.quickview.model.QuickviewConfig;
import com.littcore.saap.core.module.quickview.model.dataset.SQLDataset;
import com.littcore.saap.core.module.quickview.model.search.Search;
import com.littcore.saap.core.module.quickview.model.table.Column;
import com.littcore.saap.core.module.quickview.model.table.Table;
import com.littcore.saap.system.service.IDictParamService;
import com.littcore.saap.system.vo.DictParamVo;
import com.littcore.saap.system.webservice.IUserWebService;
import com.littcore.util.BeanCopier;
import com.littcore.util.StringUtils;
import com.littcore.web.util.WebUtils;

/**
 * @author littcai
 *
 */
public class QuickviewServiceImpl implements IQuickviewService, IQuickviewWebService {
	
	@Resource
	private BaseJdbcDao jdbDao;
	@Resource
	private QuickviewDao quickviewDao;
	@Resource
	private QuickviewFilterDao quickviewFilterDao;
	@Resource
	private IUserWebService userWebService;
	@Resource
	private IDictParamService dictParamService;
	
	/* (non-Javadoc)
	 * @see com.littcore.saap.assistant.service.IQuickviewService#save(int, java.lang.String, int, java.lang.String, java.lang.String, java.util.Map)
	 */
	public Integer save(int tenantId, String moduleCode, int userId, String name, String descr, Map<String, String> paramMap)
	{
	  Quickview quickview = new Quickview();
	  quickview.setTenantId(tenantId);
	  quickview.setModuleCode(moduleCode);
	  quickview.setName(name);
	  quickview.setDescr(descr);
	  quickview.setPublicFlag(false);
	  quickview.setAdvancedFlag(false);
	  quickview.setCreateBy(userId);
	  quickview.setCreateDatetime(new Date());
	  quickview.setUpdateDatetime(quickview.getCreateDatetime());
	  
	  return quickviewDao.save(quickview);
	}
	
	public QuickviewVo findById(int id)
	{
	  Quickview po = load(id);
	  
	  QuickviewVo vo = BeanCopier.copy(po, QuickviewVo.class);
	  return vo;
	}

  /**
   * @param id
   * @return
   */
  public Quickview load(int id)
  {
    Quickview po = quickviewDao.load(id);
    return po;
  }
  	
	public List<QuickviewVo> findByModuleAndUser(int tenantId, String moduleCode, int userId)
	{
	  List<Quickview> rsList = quickviewDao.listByModuleAndUser(tenantId, moduleCode, userId);
	  List<QuickviewVo> voList = BeanCopier.copyList(rsList, QuickviewVo.class);
	  return voList;
	}
	
	
	/* (non-Javadoc)
	 * @see com.littcore.saap.assistant.service.impl.IQuickViewService#listPage(java.lang.String, com.littcore.dao.ql.PageParam)
	 */
	@Override
	public IPageList listPage(String sql, PageParam pageParam)
	{
		IPageList pageList = jdbDao.listPage(sql, pageParam);
		
		return pageList;
	}
	
	/**
	 * Generate.
	 *
	 * @param quickViewCode the quick view code
	 * @param loginUserVo the login user vo
	 * @param request the request
	 * @return the map
	 */
	public Map<String, Object> generate(String quickViewCode, final LoginUserVo loginUserVo, WebRequest request)
	{
	  Integer qvId = Utility.parseInt(request.getParameter("qv"), null);
	  
	  Map<String, Object> resultMap = new HashMap<String, Object>();
	  
	  final int tenantId = loginUserVo.getTenantId();
	  final Locale locale = loginUserVo.toLocale();
	  
	  PageParam pageParam = WebUtils.getPageParam(request);
    pageParam.addCond("tenantId", loginUserVo.getTenantId());   
    pageParam.addCond("isDeleted", false);
    
	  //读取快速视图定义
    QuickviewConfig quickviewConfig = QuickviewManager.getInstance().getQuickView(quickViewCode);    
    //处理查询条件
    Search search = quickviewConfig.getSearch();
    List<Field> fieldList = search.getAllFieldList();
    for (Field field : fieldList) {
      //处理页面表单的传值
      if(!StringUtils.isEmpty(request.getParameter(field.getKey())))
      {
        pageParam.addCond(field.getKey(), field.parseValue(request.getParameter(field.getKey())));
      }
      
      FieldItems fieldItems = field.getItems();
      if(fieldItems==null)
        continue;
      if(FieldItems.PROVIDER_DICTPARAM.equals(fieldItems.getProvider()))
      {
        List<DictParamVo> dictParamList = dictParamService.findByType(fieldItems.getFilter(), locale);
        List<FieldItem> itemList = new ArrayList<FieldItem>(dictParamList.size());
        for (DictParamVo dictParam : dictParamList) {
          FieldItem item = new FieldItem(dictParam.getDictContent(), dictParam.getDictValue());
          itemList.add(item);
        }
        fieldItems.setItemList(itemList);
      }
    }
    
    //处理页面基于表单的过滤
    String qvKey = request.getParameter("qv_key");
    String qvValue = request.getParameter(qvKey);
    if(!StringUtils.isEmpty(qvKey) && !StringUtils.isEmpty(qvValue))
    {
      Field field = search.getField(qvKey);
      //根据Field的数据类型转换参数值类型      
      pageParam.addCond(qvKey, field.parseValue(qvValue));
    }
    
    if(qvId!=null)
    {
      //读取快速视图的条件
      Quickview quickview = this.load(qvId);
      if(quickview!=null)
      {
        List<QuickviewFilter> filterList = quickviewFilterDao.listByQuickview(qvId);        
        Map<String, QuickviewFilter> filterMap = new HashMap<String, QuickviewFilter>();
        for (QuickviewFilter quickviewFilter : filterList)
        {
          filterMap.put(quickviewFilter.getFieldName(), quickviewFilter);
        }
        
        for (Field field : fieldList) {
          QuickviewFilter filter = filterMap.get(field.getKey());
          if(filter!=null)
          {
            String paramValue = filter.getFieldValue();
            if(StringUtils.isEmpty(paramValue))
              continue;
            
            pageParam.addCond(field.getKey(), paramValue);
          }
        }
      }  
    }
    
    //处理数据源
    SQLDataset dataset = (SQLDataset)quickviewConfig.getDataset();
    IPageList pageList = this.listPage(dataset.getSql(), pageParam);
    //处理数据表格
    final Table table = quickviewConfig.getTable();
    pageList.setResultsetTransformer(new IResultsetTransformer(){

      @Override
      public List transform(List srcList) {
        for (int i = 0; i<srcList.size(); i++) 
        {
          Map<String, Object> rowMap = (Map<String, Object>)srcList.get(i);
          List<Column> columnList = table.takeConverterColumnList();
          for (Column column : columnList) {
            String converter = column.getConverter();
            if(StringUtils.endsWith(converter, "html"))  //自定义HTML内容
            {
              String html = column.getHtml();
              Map<String, Object> dataMap = new HashMap<String, Object>();
              dataMap.put("loginUser", loginUserVo);
              dataMap.put("row", rowMap);
              html = TemplateRuntime.eval(html, dataMap).toString();
              rowMap.put(column.getName(), html);
            }
            //参数字典的转换
            else if(StringUtils.startsWith(converter, "dictparam") && rowMap.containsKey(column.getName()))
            {
              String value = rowMap.get(column.getName()).toString();
              value = BeanManager.getMessage(converter+"."+value, locale);
              rowMap.put(column.getName(), value);
            }
            else if(StringUtils.startsWith(converter, "user") && rowMap.containsKey(column.getName()))
            {
              Integer userId = (Integer)rowMap.get(column.getName());
              TenantUserVo user = userWebService.findById(tenantId, userId);
              rowMap.put(column.getName(), user.getUserName());
            }
            else if(StringUtils.startsWith(converter, "i18n"))
            {
              String key = StringUtils.substringAfter(converter, "."); 
              Object value = rowMap.get(column.getName());
              if(value instanceof Boolean)
              {  
                Boolean booleanValue  = (Boolean)value;
                if(booleanValue)
                {
                  value = BeanManager.getMessage(key+".1", locale);
                }
                else {
                  value = BeanManager.getMessage(key+".0", locale);
                }
              }
              else {
                value = BeanManager.getMessage(key+"."+value, locale);
              }
              rowMap.put(column.getName(), value);
            }
          }
        } 
        return srcList;
      }
    });
    
    resultMap.put("quickviewConfig", quickviewConfig);
    //return params to response
    resultMap.put("search", search);
    resultMap.put("pageParam", pageParam);  
    resultMap.put(dataset.getId(), pageList); 
    resultMap.put("table", table);
    
    return resultMap;
	}
	

}
